package com.xiye.system.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author 西野
 * @version V1.0
 * @title Swagger2Config.java
 * @package com.xiye.system.config
 * @description RESTful Api文档
 * @date 2018-07-18
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {

    @Value("${swagger.title}")
    private String title;

    @Value("${swagger.description}")
    private String description;

    @Value("${swagger.version}")
    private String version;

    @Value("${swagger.termsOfServiceUrl}")
    private String termsOfServiceUrl;

    @Value("${swagger.contact.name}")
    private String name;

    @Value("${swagger.contact.url}")
    private String url;

    @Value("${swagger.contact.email}")
    private String email;

    /*
        Docket类的方法：
        Docket groupName(String var):设置栏目名

        Docket apiInfo(ApiInfo apiInfo):设置文档信息

        Docket pathMapping(String path):设置api根路径

        Docket protocols(Set<String> protocols):设置协议，Sets为com.goolge.common下的类，Sets.newHashSet("https","http")相当于new HashSet(){{add("https");add("http");}};

        ApiSelectorBuilder select():初始化并返回一个API选择构造器



        ApiSelectorBuilder类的方法：

        ApiSelectorBuilder apis(Predicate<RequestHandler> selector):添加选择条件并返回添加后的ApiSelectorBuilder对象

        ApiSelectorBuilder paths(Predicate<String> selector):设置路径筛选，该方法中含一句pathSelector = and(pathSelector, selector);表明条件为相与



        RequestHandlerSelectors类的方法：

        Predicate<RequestHandler> any()：返回包含所有满足条件的请求处理器的断言，该断言总为true

        Predicate<RequestHandler> none()：返回不满足条件的请求处理器的断言,该断言总为false

        Predicate<RequestHandler> basePackage(final String basePackage)：返回一个断言(Predicate)，该断言包含所有匹配basePackage下所有类的请求路径的请求处理器



        PathSelectors类的方法：

        Predicate<String> any():满足条件的路径，该断言总为true

        Predicate<String> none():不满足条件的路径,该断言总为false

        Predicate<String> regex(final String pathRegex):符合正则的路径



    设置swagger-ui.html默认路径，servlet的配置文件添加:

        <mvc:annotation-driven></mvc:annotation-driven>
        <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars"/>

        swagger-ui.html位于springfox-swagger-ui jar包中的META-INF/resources/目录下，项目编译后swagger-ui.html将添加到classpath的/META-INF/resources/下，所以添加mapping="/webjars/**" 可通过localhost:端口号/项目名/swagger-ui.html打开SwaggerUI

    常用注解:

        Swagger所有注解并非必须，若不加就只显示类目/方法名/参数名没有注释而已，但若注解中含@ApiParam不对应@RequestParam将无效果

        @Api:注解controller，value为@RequestMapping路径

        @ApiOperation:注解方法，value为简要描述,notes为全面描述,hidden=true Swagger将不显示该方法，默认为false

        @ApiParam:注解参数,hidden=true Swagger参数列表将不显示该参数,name对应参数名，value为注释，defaultValue设置默认值,allowableValues设置范围值,required设置参数是否必须，默认为false

        @ApiModel:注解Model

        @ApiModelProperty:注解Model下的属性，当前端传过来的是一个对象时swagger中该对象的属性注解就是ApiModelProperty中的value

        @ApiIgnore:注解类、参数、方法，注解后将不在Swagger UI中显示

    */

    /*
     * @Author 西野
     * @Date 2018-07-19 16:31:21
     * @Description 通过 createRestApi函数来构建一个DocketBean
     * 函数名,可以随意命名,喜欢什么命名就什么命名
     * 接口文档官方默认访问路径http://localhost:9001/swagger-ui.html(ip和端口自己定义)；swagger-bootstrap-ui默认访问地址http://localhost:9001/doc.html
     * 配置文件中有配置此处为http://localhost:9001/doc.html
     * @Param []
     * @Return springfox.documentation.spring.web.plugins.Docket
     */  
    @Bean
    public Docket createRestApi() {
        /*basePackage指向项目的controller*/
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.xiye.system.controller")).paths(PathSelectors.any()).build();
    }

    //
    //    @Bean
    //    public Docket normalUserDocket() {
    //        return new Docket(DocumentationType.SWAGGER_2)
    //                .groupName("普通用户API文档")
    //                .apiInfo(apiInfo("提供普通用户接口"))
    //                .protocols(Sets.newHashSet("https","http"))
    //                .produces(Sets.newHashSet("html/text"))
    //                .pathMapping("/")
    //                .select()
    //                .apis(RequestHandlerSelectors.basePackage(baseLocation+".controller.candidate"))//设置生成的Docket对应的Controller为candidate下的所有Controller
    //                .paths(PathSelectors.any())
    //                .build();
    //    }
    //
    //    @Bean
    //    public Docket companyUserDocket() {
    //        return new Docket(DocumentationType.SWAGGER_2)
    //                .groupName("企业用户API接口文档")
    //                .apiInfo(apiInfo("提供企业用户接口"))
    //                .pathMapping("/")
    //                .select()
    //                .apis(RequestHandlerSelectors.basePackage(baseLocation+".controller.company"))
    //                .paths(PathSelectors.any())
    //                .build();
    //    }

    /*
     * @Author 西野
     * @Date 2018-07-19 16:31:12
     * @Description 设置文档信息
     * @Param []
     * @Return springfox.documentation.service.ApiInfo
     */  
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title(title).description(description).termsOfServiceUrl(termsOfServiceUrl).contact(new Contact(name, url, email)).version(version).build();
    }
}
